// ===================================
// <copyright>
// This file is part of LABSMFController.
//
//    LABSMFController is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    LABSMFController is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with LABSMFController.  If not, see <http://www.gnu.org/licenses/>.
//    Copyright 2011 David Bakker
//
//</copyright>
// <author>David Bakker</author>
// <email>mailto:DavidFBakker@gmail.com</email>
// <created>Saturday, May 07, 2011</created>
// <lastedit>Saturday, May 07, 2011</lastedit>
// ===================================

using System;
using GHIElectronics.NETMF.FEZ;
using LABSMFController.LABS.Classses;
using LABSMFController.LABS.Devices;
using LABSMFController.LABS.Services;

namespace LABSMFController.LABS
{
    public static class BeerProgram
    {
        public static TemperatureServiceClass TemperatureService;
        private static LoggingService _loggingService;
        //  private static HttpService _httpService;
        public static BubblerServiceClass BubblerService;
        public static PumpServiceClass PumpService;
        private static readonly BeerService[] Services;
        public static HeaterServiceClass HeaterService;
        private static StreamingSocketsService _streamingSocketService;
        private static SocketsService _socketService;
        private static RelayService _relayService;
        public static PWMServiceClass PWMService;
        private static int _serviceCount;
        private static bool _enableDebug;

        public static QueueServiceClass QueueService;

        static BeerProgram()
        {
            Services = new BeerService[24];
            _serviceCount = 0;
        }

        public static bool EnableDebug
        {
            get { return _enableDebug; }
            set
            {
                if (_enableDebug == value) return;
                _enableDebug = value;
                foreach (BeerService s in Services)
                {
                    if (s == null) continue;

                    Log("Starting " + s.Description);
                    s.EnableDebug = _enableDebug;
                }
            }
        }

        public static void Initialize()
        {
            // Init Services
            TemperatureService = new TemperatureServiceClass {EnableDebug = EnableDebug};
            TemperatureService.Configure();
            TemperatureService.PanicTriggerEvent += TemperatureServicePanicTriggerEvent;
            Services[_serviceCount++] = TemperatureService;

            _loggingService = new LoggingService {EnableDebug = EnableDebug};
            _loggingService.Configure();
            Services[_serviceCount++] = _loggingService;

            //_httpService=new HttpService();
            //_httpService.Configure();
            //Services[_serviceCount++] = _httpService;

            BubblerService = new BubblerServiceClass {EnableDebug = EnableDebug};
            BubblerService.Configure();
            BubblerService.PanicTriggerEvent += BubblerServicePanicTriggerEvent;
            Services[_serviceCount++] = BubblerService;

            PumpService = new PumpServiceClass {EnableDebug = EnableDebug};
            PumpService.Configure();
            PumpService.PanicTriggerEvent += PumpServicePanicTriggerEvent;
            Services[_serviceCount++] = PumpService;

            HeaterService = new HeaterServiceClass {EnableDebug = EnableDebug};
            HeaterService.Configure();
            HeaterService.PanicTriggerEvent += HeaterServicePanicTriggerEvent;
            Services[_serviceCount++] = HeaterService;

            _streamingSocketService = new StreamingSocketsService {EnableDebug = EnableDebug};
            _streamingSocketService.Configure();
            _streamingSocketService.PanicTriggerEvent += StreamingSocketServicePanicTriggerEvent;
            Services[_serviceCount++] = _streamingSocketService;

            _socketService = new SocketsService {EnableDebug = EnableDebug};
            _socketService.Configure();
            _socketService.PanicTriggerEvent += SocketServicePanicTriggerEvent;
            Services[_serviceCount++] = _socketService;

            QueueService = new QueueServiceClass { EnableDebug = EnableDebug };
            QueueService.Configure();
            QueueService.PanicTriggerEvent += QueueServicePanicTriggerEvent;
            Services[_serviceCount++] = QueueService;

            PWMService = new PWMServiceClass { EnableDebug = EnableDebug };
            PWMService.Configure();
            PWMService.PanicTriggerEvent += PWMServicePanicTriggerEvent;
            Services[_serviceCount++] = PWMService;

            
            SetupRelayService();
                   
        }

        private static void SetupRelayService()
        {
            if (_relayService != null) return;

            _relayService = new RelayService {EnableDebug = EnableDebug};
            _relayService.Configure();
            _relayService.PanicTriggerEvent += RelayServicePanicTriggerEvent;
            Services[_serviceCount++] = _relayService;
        }

        public static void TurnOnRelay(FEZ_Components.Relay16.RelayChannel relayChannell)
        {
            SetupRelayService();
            _relayService.On(relayChannell);
        }


        public static void TurnOffRelay(FEZ_Components.Relay16.RelayChannel relayChannell)
        {
            SetupRelayService();
            _relayService.Off(relayChannell);
        }

        public static void TurnAllOffRelay()
        { 
            SetupRelayService();
            _relayService.AllOff();
        }

        private static void PWMServicePanicTriggerEvent(object sender, TriggerMessage message)
        {
            Log("PANIC PWMService  : " + message.Message);
        }

        private static void QueueServicePanicTriggerEvent(object sender, TriggerMessage message)
        {
            Log("PANIC QueueServiceP  : " + message.Message);
        }

        private static void RelayServicePanicTriggerEvent(object sender, TriggerMessage message)
        {
            Log("PANIC RelayService  : " + message.Message);
        }

        private static void SocketServicePanicTriggerEvent(object sender, TriggerMessage message)
        {
            Log("PANIC SocketService  : " + message.Message);
        }

        private static void StreamingSocketServicePanicTriggerEvent(object sender, TriggerMessage message)
        {
            Log("PANIC StreamingSocketService  : " + message.Message);
        }


        private static void PumpServicePanicTriggerEvent(object sender, TriggerMessage message)
        {
            Log("PANIC Steps  : " + message.Message);
        }

        private static void BubblerServicePanicTriggerEvent(object sender, TriggerMessage message)
        {
            Log("PANIC Bubbler  : " + message.Message);
        }

        private static void TemperatureServicePanicTriggerEvent(object sender, TriggerMessage temperatureMessage)
        {
            Log("PANIC Temperature  : " + temperatureMessage.Message);
        }

        private static void HeaterServicePanicTriggerEvent(object sender, TriggerMessage temperatureMessage)
        {
            Log("PANIC Heater : " + temperatureMessage.Message);
        }

        public static void Start()
        {
            foreach (BeerService s in Services)
            {
                if (s == null) continue;

                Log("Starting " + s.Description);
                s.Start();
            }
        }


        public static void Stop()
        {
            foreach (BeerService s in Services)
            {
                if (s == null) continue;

                Log("Stoping " + s.Description);
                s.Stop();
            }
        }

        public static int GetTemp(int tempLocation)
        {
            if (tempLocation < 0 || tempLocation >= TemperatureServiceClass.MAXProbes) return BeerDevices.TempError;

            return TemperatureService.TempProbes[tempLocation].Temperature;
        }

        public static bool GetHeaterStatus(int heaterLocation)
        {
            if (heaterLocation < 0 || heaterLocation >= HeaterServiceClass.MAXHeaters) return false;

            return HeaterService.Heaters[heaterLocation].IsOn;
        }

        public static double GetLevel(int location)
        {
            if (location < 0 || location >= BubblerServiceClass.MAXBubblers) return 0;
            return BubblerService.Bubblers[location].Volume;
        }

        public static double GetGPM(int location)
        {
            if (location < 0 || location >= BubblerServiceClass.MAXBubblers) return 0;
            return BubblerService.Bubblers[location].GPM;
        }

        public static double GetGPM10Seconds(int location)
        {
            if (location < 0 || location >= BubblerServiceClass.MAXBubblers) return 0;
            return BubblerService.Bubblers[location].GP10Seconds;
        }

        public static void SetLevelEmpty(int location, int emptyLevel)
        {
            for (int c = 0; c < BubblerServiceClass.MAXBubblers; c++)
            {
                if (BubblerService.Bubblers[c].LocationID == location)
                {
                    BubblerService.Bubblers[location].LevelEmpty = emptyLevel;
                    break;
                }
            }
        }


        public static string GetClientOutPut(Type obj)
        {
            switch (obj.Name)
            {
                case "BubblerDevice":
                    return BubblerService.GetBubblersClientOutPut();
                    
                case "HeaterDevice":
                    return HeaterService.GetHeatersClientOutPut();
                    
                case "PumpDevice":
                    return PumpService.GetPumpsClientOutPut();
                    
                case "TempProbe":
                    return TemperatureService.GetTempProbesClientOutPut();

                case "PWMValveDevice":
                    return PWMService.GetPWMClientOutPut();

                case "QueueServiceClass":
                    return QueueService.GetLocationClientOutPut();

            }
            return "";
        }

        public static string GetDescription(Type obj, int location)
        {
            switch (obj.Name)
            {
                case "BubblerDevice":
                    return BubblerService.Bubblers[location].Description;
                    
                case "HeaterDevice":
                    return HeaterService.Heaters[location].Description;
                    
                case "PumpDevice":
                    return PumpService.Pumps[location].Description;
                    
                case "TempProbe":
                    return TemperatureService.TempProbes[location].Description;

                case "PWMValveDevice":
                    return PWMService.PWMDevices[location].Description;

            }
            return "";
        }

        public static void Reset()
        {
            if (HeaterService != null) HeaterService.ResetAllHeaters();
            if (PumpService != null) PumpService.ResetAllPumps();
        }

        public static int GetLowLevel(int location)
        {
            if (location < 0 || location >= BubblerServiceClass.MAXBubblers) return 0;

            return BubblerService.Bubblers[location].LowReading;
        }

        public static void ResetLevel(int location)
        {
            if (location < 0 || location >= BubblerServiceClass.MAXBubblers) return;

            BubblerService.Bubblers[location].Reset();
        }

        public static void ResetTemps(int location)
        {
            if (location < 0 || location >= BubblerServiceClass.MAXBubblers) return;

            TemperatureService.TempProbes[location].ResetLevels();
        }


        public static int GetHighLevel(int location)
        {
            if (location < 0 || location >= BubblerServiceClass.MAXBubblers) return 0;

            return BubblerService.Bubblers[location].HighReading;
        }

        public static void Log(string message)
        {
            if (_loggingService != null)
                _loggingService.Log(message, LoggingSeverity.Normal);
        }

        public static string GetAllLogs()
        {
            if (_loggingService != null)
                return _loggingService.SendAllLogs();

            return "";
        }

        public static void Log(string message, int loggingSeverity)
        {
            if (_loggingService != null)
                _loggingService.Log(message, loggingSeverity);
        }

        public static void StartStep(int waterMovementStep)
        {
            if (PumpService != null)
                PumpService.StartStep(waterMovementStep);
        }

        public static void StopStep(int waterMovementStep)
        {
            LiquidMovementClass waterMovement = LiquidMovementUtil.LiquidMovements[waterMovementStep];

            if (waterMovement != null)
                if (PumpService != null) PumpService.StopStep(waterMovement.PumpNumber);
        }

        public static void AutoConfigure(string className)
        {
            switch (className)
            {
                case "PWM":
                    if (PWMService.CanAutoConfigureDone())
                        PWMService.AutoConfigure();
                    break;

            }
        }

        public static double GetVValveSwing(int vvalveLocaion)
        {
            return VValveDevices.VValves[vvalveLocaion].Swing;
        }

        public static void StartHeater(int heaterLocation, int temp)
        {
            HeaterService.StartHeater(heaterLocation, temp);
        }

        public static void StopHeater(int heaterLocation)
        {
            HeaterService.StopHeater(heaterLocation);
        }

        public static void SendToClients(string message)
        {
            if (_streamingSocketService != null) _streamingSocketService.SendToClients(message);
        }

        public static void VValveOn(int valveNum)
        {
            VValveDevices.VValves[valveNum].TurnOn();
        }

        public static void SetPWMValveAngle(int valveNum, int angle)
        {
            PWMService.SetPWMValveAngle(valveNum,angle);         
        }

        public static double GetPWMValveAngle(int valveNum)
        {
            return PWMService.PWMDevices[valveNum].CurrentAngle;
        }

        //public static void VValveOff(int valveNum)
        //{
        //    VValveDevices.VValves[valveNum].TurnOff();
        //}

        public static void VVTurnLevel(int valveNum, int level)
        {
            if (VValveDevices.VValves[valveNum].IsThreeWay)
            {
                if (level == VValveDevices.VValves[valveNum].ASwing)
                {
                    VValveDevices.VValves[valveNum].TurnToA();
                }
                else
                {
                    VValveDevices.VValves[valveNum].TurnToB();
                }
            }
            else
            {
                VValveDevices.VValves[valveNum].TurnLevel(level, false);
            }
        }

        public static void ValveOn(int valveNum)
        {
            ValveDevices.Valves[valveNum].TurnOn();
        }

        public static void ValveOff(int valveNum)
        {
            ValveDevices.Valves[valveNum].TurnOff();
        }
    }
}